package com.cgnpc.scp.run.utils;

import com.cgnpc.scp.common.bean.CreateFileInfo;
import com.cgnpc.scp.common.bean.ExcelCustomResultHandler;
import com.cgnpc.scp.common.service.AppConstantService;
import com.cgnpc.scp.common.service.ExcelCustomTemplateService;
import com.cgnpc.scp.common.utils.ExcelUtil;
import com.cgnpc.scp.common.utils.FileUtil;
import org.apache.commons.beanutils.BeanMap;
import org.apache.ibatis.session.SqlSession;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;

/**********************************
 * 用途说明: 用于整理导出的excel的格式的工具类
 * 作者姓名: zhangyibing
 * 创建时间: 2020年9月15日22:34:44
 ***********************************/
public class CommonExportUtil<T> {

    /**
     * @param appConstantService 主要用于获取excel存储路径
     * @param sqlSession sqlSession
     * @param titleList 标题字段名
     * @param fields 对应titleList的各个字段的属性名
     * @param mapperNameSpace 查询数据库的namespace
     * @param statement 查询数据库的namespace下的statement名
     * @param queryExample queryExample
     * @return excel导出详情结果
     * @throws Exception
     */
    public CreateFileInfo exportExcel(AppConstantService appConstantService, SqlSession sqlSession
            , List<String> titleList , List<String> fields
            , String mapperNameSpace, String statement, Object queryExample) throws Exception {
        // begin 临时路径相关
        SimpleDateFormat sdfWebLocal = new SimpleDateFormat("yyyyMM");
        String strFileFull = sdfWebLocal.format(new Date()) + "/" + "excel_export_" + System.currentTimeMillis() + "-" + UUID.randomUUID().toString() + ".xlsx";
        String tempCreateFileDir = appConstantService.getTempCreateFileDir();
        File webLocalFile = new File(new File(tempCreateFileDir), strFileFull);

        // 创建多层目录
        FileUtil.mkdirs(webLocalFile.getParentFile());
        // end 临时路径相关

        // 创建返回对象
        CreateFileInfo createFileInfo = new CreateFileInfo();
        createFileInfo.setWebLocalFile(webLocalFile);
        createFileInfo.setWebRequestUrl(appConstantService.getWebTempFileRootUrl() + strFileFull);

        // mappedStatementId为具体指向的方法
        String mappedStatementId = mapperNameSpace + "." + statement;

        final AtomicInteger rowIndex = new AtomicInteger();
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        final Sheet[] arrSheet = {null};
        // 每个Excel的CellStyle是有数量限制的，尽量使用相同的CellStyle
        final CellStyle[] arrCellStyleTitle = {null};

        ExcelCustomResultHandler<T> excelResultHandler = (resultContext, workbook) -> {
            T resultObject = resultContext.getResultObject();

            formatSheetStyle(arrSheet, arrCellStyleTitle, titleList, workbook, rowIndex);

            // 创建数据数组，元素应该对应titleList
            BeanMap map = new BeanMap(resultObject);

            List<Object> dataList = new ArrayList<>();
            for (String field : fields) {
                dataList.add(map.get(field) == null ? "" : map.get(field));
            }

            // 创建row
            Row row = arrSheet[0].createRow(rowIndex.getAndIncrement());
            Cell cell = null;

            // 创建并设置cell
            for (int aaa = 0; aaa < dataList.size(); aaa++) {
                cell = row.createCell(aaa);
                ExcelUtil.setCellValue(cell, dataList.get(aaa), sdf);
            }
        };

        ExcelCustomTemplateService.createXlsxToWebDir(
                sqlSession,
                mappedStatementId,
                queryExample,
                webLocalFile,
                excelResultHandler
        );
        return createFileInfo;
    }

    private static void formatSheetStyle(Sheet[] arrSheet, CellStyle[] arrCellStyleTitle
            , List<String> titleList, SXSSFWorkbook workbook
            , AtomicInteger rowIndex){
        if (arrSheet[0] == null) {
            // 创建sheet
            arrSheet[0] = workbook.createSheet();
            // 创建row
            Row row = arrSheet[0].createRow(rowIndex.getAndIncrement());
            Cell cell = null;

            if (arrCellStyleTitle[0] == null) {
                // begin 创建字体
                Font fontTitle = workbook.createFont();
                // make it blue
                fontTitle.setColor(Font.COLOR_RED);
                // end 创建字体

                // begin 创建单元格样式
                CellStyle cellStyleTitle = workbook.createCellStyle();
                cellStyleTitle.setFont(fontTitle);
                // end 创建单元格样式
                arrCellStyleTitle[0] = cellStyleTitle;
            }

            // 创建并设置cell
            for (int aaa = 0; aaa < titleList.size(); aaa++) {
                cell = row.createCell(aaa);
                // 设置单元格样式
                if (arrCellStyleTitle[0] != null) {
                    cell.setCellStyle(arrCellStyleTitle[0]);
                }

                ExcelUtil.setCellValue(cell, titleList.get(aaa));
            }
        }
    }

}
